/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.google.code.peersim.pastry.protocol;

import com.google.code.peersim.pastry.protocol.PastryJoinLsnrIfc.JoinedInfo;

/**
 * Interface that components willing to receive notifications related to
 * resource-assignment events must implement.
 *
 * @author frusso
 * @version 0.1
 * @since 0.1
 */
public interface PastryResourceAssignLsnrIfc {

  /**
   * Notifies that a resource has been assigned.<br>
   * <b>Note:</b> this method is used to notify the <b>assginer</b>, not the <i>assignee</i>.
   *
   * @param info The notification
   */
  public void resourceAssigned(ResourceAssignedInfo info);

  /**
   * Notifies that a resource has been received.<br>
   * <b>Note:</b> this method is used to notify the <b>assginee</b>, not the <i>assigner</i>.
   *
   * @param info The notification
   */
  public void resourceReceived(ResourceReceivedInfo info);

  /**
   * Notifies that a resource has been routed to another destination.
   *
   * @param info The notification
   */
  public void resourceRouted(ResourceRoutedInfo info);

  /**
   * Immutable class for representing notifications for resource-assignment events.
   *
   * @author frusso
   * @version 0.1
   * @since 0.1
   */
  public static class ResourceAssignedInfo extends JoinedInfo {

    private final PastryNode node;
    private final PastryResource<?> resource;

    /**
     * Constructor.
     *
     * @param res The assigned resource
     * @param hops The hops
     * @param node The node the resource has been assigned to
     */
    public ResourceAssignedInfo(PastryResource<?> res, int hops, PastryNode node) {
      super(hops,node.getPastryId());
      this.resource = res;
      this.node = node;
    }

    /**
     * Returns the assigned resource.
     *
     * @return The resource
     */
    public PastryResource getResource() {
      return resource;
    }

    /**
     * Returns the assignee.
     *
     * @return The assignee
     */
    public PastryNode getNode() {
      return node;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
      return "RES_ASSIGNED node: "+node+" resource: "+resource;
    }
  }

  /**
   * Immutable class for representing notifications for resource-reception events.
   *
   * @author frusso
   * @version 0.1
   * @since 0.1
   */
  public static class ResourceReceivedInfo extends ResourceAssignedInfo {

    public ResourceReceivedInfo(PastryResource<?> res, int hops, PastryNode node) {
      super(res, hops, node);
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
      return "RES_RECEIVED node: "+getNode()+" resource: "+getResource();
    }
  }

  /**
   * Immutable class for representing notifications for resource-routing events.
   *
   * @author frusso
   * @version 0.1
   * @since 0.1
   */
  public static class ResourceRoutedInfo extends ResourceAssignedInfo {

    public ResourceRoutedInfo(PastryResource<?> res, int hops, PastryNode node) {
      super(res, hops, node);
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
      return "RES_ROUTED node: "+getNode()+" resource: "+getResource();
    }
  }
}